feat(01KVW2GD): retry a thrown courier hiccup on a read-only setup seam#445
Merged
jackmcintyre merged 1 commit intoJun 24, 2026
Conversation
A thrown courier error (the courier emitted its StructuredOutput call as literal text and never returned a structured result -> agent() throws) used to hit the seam() catch and re-throw on attempt #1, bypassing the retryable seam's attempts=3 loop. A read-only preflight seam (preflight:standards, retryable=true) therefore died on the first hiccup, aborting the whole run before any story was claimed. Treat a thrown courier error like a garbled relay: for a retryable seam with attempts remaining, record the sentinel and retry; only propagate after attempts are exhausted. SAFE because retryable is set only on read-only / idempotent seams. A non-retryable (mutating) seam has attempts=1, so it still re-throws on the FIRST failure with no retry (no double-apply). Extends the run-fault-injection harness with a transient-throw knob (throwSeamTimes) and two cases: AC1 a transient throw at the read-only preflight seam is retried + recovers (run proceeds to claim + build); AC2 the same hiccup at the mutating verdict seam stops loudly on the first failure, invoked exactly once. Claude-Session: https://claude.ai/code/session_01EE2ncqkqh3u5af93Uf3bDA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
An unattended run could die at the starting line. One of the run's read-only setup checks (the pre-flight
getStatus/standards check) relies on a one-shot AI courier to relay its result. If that courier hiccups — emits its result as plain text instead of through the structured tool, so nothing comes back — the run used to abort immediately, before claiming or building a single story.The setup check already advertised "3 attempts," but a thrown courier error skipped the retry loop entirely and bubbled up on the first try. This change makes a thrown courier error retry just like a garbled-but-returned one: a read-only setup check now quietly retries and recovers, and the run carries on to claim and build.
Crucially, this only affects read-only / idempotent steps. A state-changing step (e.g. recording a verdict) is never retried — it still stops loudly on the first failure, so no state-changing action is ever repeated.
Acceptance criteria
How it was tested
Both ACs are demonstrated by two new integration cases in
run-fault-injection.test.ts, which run the realrun.workflow.jsbody verbatim through the existing AsyncFunction harness (no production behaviour mocked, only the seam surface stubbed):throwSeamTimesknob (a courier that throws the first N calls then succeeds), modelling a transient hiccup the retry loop can recover from.preflight:standardsseam → asserts the seam is invoked twice (throw + recovering retry), the retry is narrated, the story is claimed, and the run reachesqueue-emptied. Verified this case goes RED against the old code (which aborts pre-claim).verdict:seam → asserts the story buckets asworker-threwon the first failure and the verdict courier is invoked exactly once (no double-apply).Full suite green: 3830 tests pass, coverage lines 86.26% (≥ 86% CI gate).
pnpm -r buildgreen; nodistdrift (the fix is in the non-bundledrun.workflow.js+ the test file). Nothing under.flow/touched.https://claude.ai/code/session_01EE2ncqkqh3u5af93Uf3bDA